package com.zdgk.core.control.forward.network.listener;

import cn.hutool.extra.spring.SpringUtil;
import cn.hutool.json.JSONArray;
import cn.hutool.json.JSONObject;
import cn.hutool.json.JSONUtil;
import com.zdgk.core.control.config.ControlConfigInfo;
import com.zdgk.core.control.read.modbus.cache.entity.RuleValueEntity;
import com.zdgk.core.web.service.ConfigService;
import org.openmuc.j60870.ASdu;
import org.openmuc.j60870.ASduType;
import org.openmuc.j60870.CauseOfTransmission;
import org.openmuc.j60870.Connection;
import org.openmuc.j60870.ie.*;

import javax.annotation.Resource;
import java.io.IOException;
import java.util.*;

public class Info104 {
    private static ControlConfigInfo controlConfigInfo;
    static {
        ConfigService configService = SpringUtil.getBean("configService");
        controlConfigInfo = configService.getControlKey();
    }

    public static final Map<String,Connection> connectionList = new HashMap<>();
    final private static Integer DEVICE_IOA_MAX_COUNT = 71;
    final private static Integer DEVICE_IOA_SWITCH_MAX_COUNT = 26;
    public static void sendChange(Connection connection,RuleValueEntity ruleValueEntity, Integer deviceIndex, ControlConfigInfo controlConfigInfo){

        if("analog".equals(ruleValueEntity.getForwardType())){
            analogChange(connection,ruleValueEntity, deviceIndex, controlConfigInfo);
        }
        if("switch".equals(ruleValueEntity.getForwardType())){
            splitChange(connection,ruleValueEntity, deviceIndex, controlConfigInfo);
        }

    }
    private static int computeAnalogCount(int index){
        int count = 0;
        for (int i = 0; i < index; i++) {
            count = count + controlConfigInfo.getServerPointCountArr()[i];
        }
        return count;
    }
    private static int computeSwitchCount(int index){
        int count = 0;
        for (int i = 0; i < index; i++) {
            count = count + controlConfigInfo.getServerSwitchPointCountArr()[i];
        }
        return count;
    }
    private static void analogChange(Connection connection,RuleValueEntity ruleValueEntity, Integer deviceIndex, ControlConfigInfo controlConfigInfo) {
        InformationObject[] ioaGroup = new InformationObject[1];
        ioaGroup[0] = new InformationObject(
                controlConfigInfo.getThreeAdd104() + ruleValueEntity.getAddress104() + computeAnalogCount(deviceIndex),
                new IeShortFloat(ruleValueEntity.getForwardValue()),
                new IeQuality(false, false, false, false, false)
        );
        ASdu dataResponse = new ASdu(
                ASduType.M_ME_NC_1,
                false,
                CauseOfTransmission.SPONTANEOUS,
                false,
                false,
                0,
                1,
                ioaGroup
        );
        if(connection==null){
            Set<Map.Entry<String, Connection>> entries = connectionList.entrySet();
            entries.forEach(x->{
                try {
                    x.getValue().send(dataResponse);
                } catch (IOException e) {
                    throw new RuntimeException(e);
                }
            });
        }else {
            try {
                connection.send(dataResponse);
            } catch (IOException e) {
                throw new RuntimeException(e);
            }
        }
    }
    private static void splitChange(Connection connection,RuleValueEntity ruleValueEntity, Integer deviceIndex, ControlConfigInfo controlConfigInfo) {
        String addressInfo104 = ruleValueEntity.getAddressInfo104();
        JSONArray jsonArray = JSONUtil.parseArray(addressInfo104);
        InformationObject[] ioaGroup = new InformationObject[jsonArray.size()];
        for (int j = 0; j < jsonArray.size(); j++) {
            JSONObject json = jsonArray.getJSONObject(j);
            boolean on = false;
            String tv = json.getStr("tv");
            String [] tvs = tv.split(",");
            for (int s = 0; s < tvs.length; s++) {
                Float tvf = Float.valueOf(tvs[s]);
                if(tvf.compareTo(ruleValueEntity.getForwardValue())==0){
                    on = true;
                }
            }
            ioaGroup[j] = new InformationObject(
                    controlConfigInfo.getThreeSwitchAdd104() + json.getInt("address") + computeSwitchCount(deviceIndex),
                    new InformationElement[][]{
                            {new IeSinglePointWithQuality(on, false, false, false, false)}}
            );
        }
        ASdu dataResponse = new ASdu(
                ASduType.M_SP_NA_1,
                false,
                CauseOfTransmission.SPONTANEOUS,
                false,
                false,
                0,
                1,
                ioaGroup
        );
        if(connection==null){
            Set<Map.Entry<String, Connection>> entries = connectionList.entrySet();
            entries.forEach(x->{
                try {
                    x.getValue().send(dataResponse);
                } catch (IOException e) {
                    throw new RuntimeException(e);
                }
            });
        }else {
            try {
                connection.send(dataResponse);
            } catch (IOException e) {
                throw new RuntimeException(e);
            }
        }

    }
}
